package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"os"
)

// 面向过程的编程 --思维模式，做什么事情，实现功能
// 面向对象的编程 --着重于谁去做
// 结构体的设定 -- 属性，方法

// 绑定登录注册方法
// 接受用户名、密码等等参数， 返回error
type User struct {
	UserName   string
	UserPasswd string
}

type System struct {
	SysName  string
	SysUsers map[string]User
}

func main() {
	sys1 := System{
		SysName:  "购物系统",
		SysUsers: map[string]User{},
	}
	sys2 := System{
		SysName:  "生鲜系统",
		SysUsers: map[string]User{},
	}

	fmt.Println("1.购物系统\n2.生鲜系统\n3.输入任意键退出")
	fmt.Println("请输入你的选择:")
	var sysChoice int
	fmt.Scanln(&sysChoice)
	var sys System
	if sysChoice == 1 {
		sys = sys1
	} else if sysChoice == 2 {
		sys = sys2
	} else {
		return
	}

	var choice string
	fmt.Println("欢迎进入", sys.SysName)
	fmt.Println("1.注册\n2.登录")
	fmt.Println("请输入你的选择:")
	fmt.Scan(&choice)
	switch choice {
	case "1":
		for {
			fmt.Println("请输入创建的用户名和密码：")
			fmt.Println("用户名:")
			var userName string
			fmt.Scan(&userName)
			fmt.Println("密码:")
			var userPasswd string
			fmt.Scan(&userPasswd)
			user := UserInfo(userName, userPasswd)
			sys.SysUsers[userName] = user
			fmt.Println("是否继续？\n1.输入1继续\n2.输入任意键取消")
			var continueChoice int
			fmt.Scan(&continueChoice)
			if continueChoice != 1 {
				break
			}
		}
		//添加用户至本地
		mapToLocalJson(sys.SysUsers, sys)
	case "2":
		fmt.Println("请输入登录用户名和密码：")
		fmt.Println("用户名:")
		var userName string
		fmt.Scan(&userName)
		fmt.Println("密码:")
		var userPasswd string
		fmt.Scan(&userPasswd)

		//
		var usersInfo map[string]User
		usersInfo = jsonLocalToMap(sys)
		// 定义一个要检查的key
		keyToCheck := userName
		// 尝试访问该key
		if value, exists := usersInfo[keyToCheck]; exists {

			//fmt.Println("用户", keyToCheck, "存在\n")
			if userPasswd == value.UserPasswd {
				fmt.Println("密码正确，登录成功！")
			} else {
				fmt.Println("error:", errors.New("密码错误,登录失败！"))
			}
		} else {
			fmt.Println("error:", errors.New("用户"+keyToCheck+"不存在！"))
		}
	}

}

func UserInfo(userName string, userPasswd string) User {
	var user User
	user.UserName = userName
	user.UserPasswd = userPasswd
	return user
}

func mapToLocalJson(srcMap map[string]User, system System) {

	// 将map转换为JSON格式的字节切片
	jsonData, err := json.MarshalIndent(srcMap, "", "  ")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	// 打开（或创建）一个文件用于写入
	file, err := os.Create(system.SysName + "UserInfo.json")
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	defer file.Close()

	// 将JSON字节切片写入文件
	_, err = file.Write(jsonData)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}

	fmt.Println("JSON data written to data.json successfully")
}

func jsonLocalToMap(system System) map[string]User {

	// 在实际应用中，你会从文件中读取JSON数据
	data, err := os.ReadFile(system.SysName + "UserInfo.json")
	if err != nil {
		fmt.Println(errors.New("不存在" + system.SysName + "的用户信息！"))
	}
	jsonData := string(data)

	// 将JSON字符串解析为map[string]interface{}
	var rawMap map[string]interface{}
	err = json.Unmarshal([]byte(jsonData), &rawMap)
	if err != nil {
		log.Fatal(err)
	}

	// 创建一个新的map来存储转换后的User对象
	userMap := make(map[string]User)

	// 遍历rawMap，将每个值转换为User并存储在userMap中
	for key, value := range rawMap {
		// 将interface{}断言为map[string]interface{}，然后转换为User
		userValue, ok := value.(map[string]interface{})
		if !ok {
			log.Fatalf("value for key %q is not a map[string]interface{}", key)
		}

		// 创建一个User实例并填充数据
		var user User
		// 这里需要手动处理每个字段
		if name, ok := userValue["UserName"].(string); ok {
			user.UserName = name
		}
		if passwd, ok := userValue["UserPasswd"].(string); ok {
			user.UserPasswd = passwd
		}

		// 将User实例添加到map中
		userMap[key] = user
	}
	// 打印结果以验证
	//fmt.Println(userMap)

	return userMap
}
